package com.coolw.file.util;

import org.dromara.hutool.core.codec.binary.Base64;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

/**
 * AES工具类
 *
 * @author coolw
 * @date 2023/10/19 14:15
 */
public final class AESUtil {

    private static final String AES_ALGORITHM = "AES";

    /**
     * 获取cipher
     */
    private static Cipher getCipher(byte[] key, int model) throws Exception {
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
        Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
        cipher.init(model, secretKeySpec);
        return cipher;
    }

    /**
     * AES加密
     */
    public static String encrypt(String data, String key) throws Exception {
        return encrypt(data.getBytes(StandardCharsets.UTF_8), key.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * AES加密
     */
    public static String encrypt(byte[] data, byte[] key) throws Exception {
        Cipher cipher = getCipher(key, Cipher.ENCRYPT_MODE);
        return Base64.encode(cipher.doFinal(data));
    }

    /**
     * AES解密
     */
    public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
        Cipher cipher = getCipher(key, Cipher.DECRYPT_MODE);
        return cipher.doFinal(Base64.decode(data));
    }

    /**
     * AES解密
     */
    public static String decrypt(String data, String key) throws Exception {
        Cipher cipher = getCipher(key.getBytes(StandardCharsets.UTF_8), Cipher.DECRYPT_MODE);
        byte[] bytes = cipher.doFinal(Base64.decode(data.getBytes(StandardCharsets.UTF_8)));
        return new String(bytes, StandardCharsets.UTF_8);
    }

    public static String createAesKey() throws Exception {
        KeyGenerator kg = KeyGenerator.getInstance("AES");
        //下面调用方法的参数决定了生成密钥的长度，可以修改为128, 192或256
        kg.init(128);
        SecretKey sk = kg.generateKey();
        byte[] b = sk.getEncoded();
        return Base64.encode(b);
    }


    public static void main(String[] args) throws Exception {
        // 生成aesKey
        String aesKey = createAesKey();
        System.out.println(aesKey);

        String content = readFile("templates/agreement.html");

        //加密
        System.out.println("encrypt param:" + content);
        String encode = AESUtil.encrypt(content, aesKey);
        System.out.println("encrypt :" + encode);

        // 解密
        String decoded = AESUtil.decrypt(encode, aesKey);
        System.out.println("decrypt :" + decoded);
    }

    public static String readFile(String filePath) throws Exception {
        Resource resource = new ClassPathResource(filePath);
        byte[] bytes = toByteArray(resource.getInputStream());
        return new String(bytes, StandardCharsets.UTF_8);
    }

    public static byte[] toByteArray(InputStream input) throws IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024 * 4];
        int n = 0;
        while (-1 != (n = input.read(buffer))) {
            output.write(buffer, 0, n);
        }
        return output.toByteArray();
    }
}
